//@author A0101119Y
#include <string>
#include "stdafx.h"
#include "CppUnitTest.h"
#include <fstream>
#include <sstream>
#include <algorithm>
#include <iterator>


using namespace Microsoft::VisualStudio::CppUnitTestFramework;
using namespace Twentyfifth;
using namespace std;

namespace StorageUnitTesting {
	std::string testFile = "test.txt";
	static const std::string FILE_DB_TEMPLATE = "dbtemplate";
	StorageMgr storagemgr;
	DbMgr dbmgr;
	GCalMgr gcalmgr;
	GCalParser parser;
	//GCalAuthHandler gcalauth;
	FileReader filereader;
	FileWriter filewriter;
	//GCalRequestHandler handler;
	int EXISTING_TASKS = 3;
	TEST_CLASS(StorageUnitTest) {
		TEST_METHOD_INITIALIZE(ObjectSetup) {
			// Initialize with 3 tasks.	
			storagemgr.StorageMgr::StorageMgr(testFile);
			std::string TODO_DESC = "Buy milk";
			std::string DEADLINE_DESC = "Finish CS2103 assignment";
			std::string TIMED_DESC = "Dinner with family";
			std::string TIMED_VENUE = "Longhouse";
			Task t;
			t.setTaskType(STRING_TASKTYPE_TODO);
			t.setDescription(TODO_DESC);
			storagemgr.addTask(t);
			t.setTaskType(STRING_TASKTYPE_DEADLINE);
			t.setDeadline(DateTime(11, 00, 27, 3, 2014));
			t.setDescription(DEADLINE_DESC);
			storagemgr.addTask(t);
			t.setDeadline(DateTime(DateTime::DateTime()));
			t.setTaskType(STRING_TASKTYPE_TIMED);
			t.setStart(DateTime(19, 0, 28, 3, 2014));
			t.setEnd(DateTime(20, 0, 28, 3, 2014));
			t.setDescription(TIMED_DESC);
			t.setVenue(TIMED_VENUE);
			storagemgr.addTask(t);
		}
		TEST_METHOD_CLEANUP(ObjectReset) {
			storagemgr.clearTasks();
			storagemgr.StorageMgr::~StorageMgr();
		}
		TEST_METHOD(DateTime_Comparison_Operator) {
			DateTime x(15, 30, 5, 11, 2014);
			DateTime y(15, 10, 5, 11, 2014);
			Assert::IsFalse(x < y);
			Assert::IsFalse(x <= y);
			Assert::IsTrue(x > y);
			Assert::IsTrue(x >= y);
		}
		TEST_METHOD(StorageMgr_TestTaskExistence) {
			Status status = storagemgr.viewTasks();
			Assert::AreEqual(3, (int)status.tasks.size());
		}
		TEST_METHOD(StorageMgr_DeleteTask) {
			// check for Status - error not found for invalid deletion.
			storagemgr.clearTasks();
			Task t;
			std::string DESC = "Random task";
			t.setTaskType(STRING_TASKTYPE_TODO);
			t.setDescription(DESC);
			Assert::AreEqual((int)Status::ERR_NOT_FOUND, (int)storagemgr.deleteTask(1).code);
			storagemgr.addTask(t);
			Assert::AreEqual((int)Status::OK, (int)storagemgr.deleteTask(EXISTING_TASKS + 1).code);
		}
		// for three following methods: check for Status and matching entries for entered tasks.
		TEST_METHOD(StorageMgr_AddTodoTask) {
			Task t;
			std::string DESC = "Buy milk";
			t.setTaskType(STRING_TASKTYPE_TODO);
			t.setDescription(DESC);
			Assert::AreEqual((int)Status::OK, (int)storagemgr.addTask(t).code);
			Assert::AreEqual(DESC, storagemgr.viewTasks().tasks[3].getDescription());
		}
		TEST_METHOD(StorageMgr_AddDeadlineTask) {
			Task t;
			std::string DESC = "Finish CS2103 assignment";
			t.setTaskType(STRING_TASKTYPE_DEADLINE);
			t.setDeadline(DateTime(11, 00, 27, 3, 2014));
			t.setDescription(DESC);
			Assert::AreEqual((int)Status::OK, (int)storagemgr.addTask(t).code);
			Assert::AreEqual(11, storagemgr.viewTasks().tasks[3].getDeadline().getHour());
			Assert::AreEqual(0, storagemgr.viewTasks().tasks[3].getDeadline().getMinute());
			Assert::AreEqual(27, storagemgr.viewTasks().tasks[3].getDeadline().getDay());
			Assert::AreEqual(3, storagemgr.viewTasks().tasks[3].getDeadline().getMonth());
			Assert::AreEqual(2014, storagemgr.viewTasks().tasks[3].getDeadline().getYear());
			Status status = storagemgr.viewTasks();
			Assert::AreEqual(4, (int)status.tasks.size());
		}
		TEST_METHOD(StorageMgr_AddTimedTask) {
			Task t;
			std::string DESC = "Dinner with family";
			std::string VENUE = "Longhouse";
			t.setTaskType(STRING_TASKTYPE_TIMED);
			t.setStart(DateTime(19, 0, 28, 3, 2014));
			t.setEnd(DateTime(20, 0, 28, 3, 2014));
			t.setDescription(DESC);
			t.setVenue(VENUE);
			Assert::AreEqual((int)Status::OK, (int)storagemgr.addTask(t).code);
			Assert::AreEqual(DESC, storagemgr.viewTasks().tasks[3].getDescription());
			Assert::AreEqual(VENUE, storagemgr.viewTasks().tasks[3].getVenue());
		}
		TEST_METHOD(StorageMgr_ViewTasks) {
			std::string DESC_TASK1 = "Buy milk";
			std::string DESC_TASK2 = "Finish CS2103 assignment";
			DateTime DATETIME_TASK2 = DateTime(11, 00, 27, 3, 2014);
			Status stuff = storagemgr.viewTasks();
			Assert::AreEqual(EXISTING_TASKS, (int)stuff.tasks.size());
			Assert::AreEqual(DATETIME_TASK2.getDay(), stuff.tasks[1].getDeadline().getDay());
			Assert::AreEqual(DATETIME_TASK2.getMonth(), stuff.tasks[1].getDeadline().getMonth());
			Assert::AreEqual(DATETIME_TASK2.getYear(), stuff.tasks[1].getDeadline().getYear());
			Assert::AreEqual(DATETIME_TASK2.getHour(), stuff.tasks[1].getDeadline().getHour());
			Assert::AreEqual(DATETIME_TASK2.getMinute(), stuff.tasks[1].getDeadline().getMinute());
		}
		TEST_METHOD(StorageMgr_EditTask) {
			Assert::AreEqual(3, (int)storagemgr.viewTasks().tasks.size());
			std::string DESC_TASK1 = "Sell milk";
			Status stuff = storagemgr.editTask(1, TaskParams::DESCRIPTION, DESC_TASK1);
			Assert::AreEqual((int)Status::OK, (int)stuff.code);
			stuff = storagemgr.viewTasks();
			Assert::AreEqual(DESC_TASK1, stuff.tasks[0].getDescription());
			DateTime DATETIME_TASK2 = DateTime(20, 30);
			stuff = storagemgr.editTask(2, TaskParams::TIME_DEADLINE, DATETIME_TASK2);
			Assert::AreEqual((int)Status::OK, (int)stuff.code);
			stuff = storagemgr.viewTasks();
			Assert::AreNotEqual(DATETIME_TASK2.getHour(), stuff.tasks[1].getStart().getHour());
			Assert::AreEqual(DATETIME_TASK2.getHour(), stuff.tasks[1].getDeadline().getHour());
			Assert::AreEqual(DATETIME_TASK2.getMinute(), stuff.tasks[1].getDeadline().getMinute());
			DateTime DATETIME_TASK3_START = DateTime(12, 30, 11, 1, 2014);
			DateTime DATETIME_TASK3_END = DateTime(21, 45, 29, 3, 2014);
			Assert::AreNotEqual(DATETIME_TASK3_START.getDay(), stuff.tasks[2].getStart().getDay());
			Assert::AreNotEqual(DATETIME_TASK3_START.getMonth(), stuff.tasks[2].getStart().getMonth());
			stuff = storagemgr.editTask(3, TaskParams::TIME_END, DATETIME_TASK3_END);
			stuff = storagemgr.editTask(3, TaskParams::DATE_END, DATETIME_TASK3_END);
			stuff = storagemgr.editTask(3, TaskParams::TIME_START, DATETIME_TASK3_START);
			stuff = storagemgr.editTask(3, TaskParams::DATE_START, DATETIME_TASK3_START);
			Assert::AreEqual((int)Status::OK, (int)stuff.code);

			stuff = storagemgr.viewTasks();
			Assert::AreEqual(DATETIME_TASK3_END.getDay(), stuff.tasks[2].getEnd().getDay());
			Assert::AreEqual(DATETIME_TASK3_END.getMonth(), stuff.tasks[2].getEnd().getMonth());
			Assert::AreEqual(DATETIME_TASK3_END.getYear(), stuff.tasks[2].getEnd().getYear());
			Assert::AreEqual(DATETIME_TASK3_START.getDay(), stuff.tasks[2].getStart().getDay());
			Assert::AreEqual(DATETIME_TASK3_START.getMonth(), stuff.tasks[2].getStart().getMonth());
			Assert::AreEqual(DATETIME_TASK3_START.getYear(), stuff.tasks[2].getStart().getYear());
			Assert::IsFalse(stuff.tasks[0].isDone());
			Assert::IsFalse(stuff.tasks[1].isDone());
			storagemgr.editTask(1, TaskParams::DONE, true);
			storagemgr.editTask(2, TaskParams::DONE, true);
			stuff = storagemgr.viewTasks();
			Assert::IsTrue(stuff.tasks[0].isDone());
			Assert::IsTrue(stuff.tasks[1].isDone());

			string NEW_VENUE = "John's house";
			Assert::AreNotEqual(NEW_VENUE, stuff.tasks[2].getVenue());
			storagemgr.editTask(3, TaskParams::VENUE, NEW_VENUE);
			stuff = storagemgr.viewTasks();
			Assert::AreEqual(NEW_VENUE, stuff.tasks[2].getVenue());


		}
		TEST_METHOD(StorageMgr_SearchTask_String) {
			std::string SEARCHSTRING_FAIL = "CS2103a";
			std::string SEARCHSTRING_SUCCESS = "CS2103";
			std::string DESC = "Finish CS2103 assignment";
			Status stuff = storagemgr.searchTasks(SEARCHSTRING_FAIL);
			Assert::AreEqual((int)Status::ERR_NO_RESULT, (int)stuff.code);
			stuff = storagemgr.searchTasks(SEARCHSTRING_SUCCESS);
			Assert::AreEqual((int)Status::OK, (int)stuff.code);
			Assert::AreEqual((int)1, (int)stuff.tasks.size());
			Assert::AreEqual(DESC, stuff.tasks[0].getDescription());
		}
		TEST_METHOD(StorageMgr_SearchTask_Date) {
			DateTime DATETIME_NONSENSE(29, 3, 2014);
			Status stuff = storagemgr.searchTasks(DATETIME_NONSENSE);
			Assert::IsTrue(stuff.tasks.empty());
			DateTime DATETIME_WAYEARLIERFORDEADLINE(30, 11, 2013);
			Status stuff2 = storagemgr.searchTasks(DATETIME_WAYEARLIERFORDEADLINE);
			Assert::IsFalse(stuff2.tasks.empty());
			DateTime DATETIME_TASK(28, 3, 2014);
			Status stuff3 = storagemgr.searchTasks(DATETIME_TASK);
			Assert::IsFalse(stuff2.tasks.empty());
		}
		TEST_METHOD(StorageMgr_Delete_Undelete) {
			Status status1 = storagemgr.viewTask(1);
			Assert::IsFalse(status1.tasks.empty());

			storagemgr.deleteTask(1);
			Status status2 = storagemgr.viewTasks();
			Assert::IsFalse(status2.tasks.empty());
			size_t expectedSize = 2;
			Assert::AreEqual(expectedSize, status2.tasks.size());

			Status status3 = storagemgr.viewTask(1);
			Assert::IsTrue(status3.tasks.empty());
			
			storagemgr.undeleteTask(1);
			Status status4 = storagemgr.viewTask(1);
			Assert::IsFalse(status4.tasks.empty());

			storagemgr.deleteTask(1, true);
			Status status5 = storagemgr.viewTask(1);
			Assert::IsTrue(status5.tasks.empty());
		}
		TEST_METHOD(StorageMgr_NonsenseEdits) {
			DateTime NONSENSE_DATETIME(12, 00, 1, 1, 2014);
			string NONSENSE_STRING = "blah blah";
			Status e;
			e = storagemgr.editTask(1, TaskParams::DATE_DEADLINE, true);
			Assert::AreNotEqual((int)Status::OK, (int)e.code);
			e = storagemgr.editTask(1, TaskParams::DESCRIPTION, true);
			Assert::AreNotEqual((int)Status::OK, (int)e.code);
			e = storagemgr.editTask(1, TaskParams::DESCRIPTION, NONSENSE_DATETIME);
			Assert::AreNotEqual((int)Status::OK, (int)e.code);
			e = storagemgr.editTask(1, TaskParams::DONE, NONSENSE_DATETIME);
			Assert::AreNotEqual((int)Status::OK, (int)e.code);
			e = storagemgr.editTask(1, TaskParams::DONE, NONSENSE_STRING);
			Assert::AreNotEqual((int)Status::OK, (int)e.code);
			e = storagemgr.editTask(1, TaskParams::DATE_DEADLINE, NONSENSE_STRING);
			Assert::AreNotEqual((int)Status::OK, (int)e.code);
			e = storagemgr.editTask(1, TaskParams::DONE, true);

			Assert::AreEqual((int)Status::OK, (int)e.code);
			e = storagemgr.editTask(2, TaskParams::DATE_DEADLINE, NONSENSE_DATETIME);
			Assert::AreEqual((int)Status::OK, (int)e.code);
			e = storagemgr.editTask(3, TaskParams::VENUE, NONSENSE_STRING);
			Assert::AreEqual((int)Status::OK, (int)e.code);
			
			e = storagemgr.undeleteTask(4);
			Assert::AreNotEqual((int)Status::OK, (int)e.code);

			Task t;
			t.setId(1);
			t.setDescription(NONSENSE_STRING);
			e = storagemgr.addTask(t);
			Assert::AreNotEqual((int)Status::OK, (int)e.code);

		}
	};

	TEST_CLASS(DbMgrUnitTest) {
		TEST_METHOD_INITIALIZE(ObjectSetup) {
			dbmgr.DbMgr::DbMgr();
		}
		TEST_METHOD_CLEANUP(ObjectReset) {
			dbmgr.DbMgr::~DbMgr();
		}
		TEST_METHOD(DbMgr_LoadToDatabaseTest) {

		}
	};

	//TEST_CLASS(FileWriterUnitTest) {
	//	TEST_METHOD_INITIALIZE(ObjectSetup) {
	//		filewriter.FileWriter::FileWriter(testFile);
	//	}
	//	TEST_METHOD_CLEANUP(ObjectReset) {
	//		filewriter.FileWriter::~FileWriter();
	//	}
	//	TEST_METHOD(DbMgr_LoadFromFile) {

	//	}
	//};

	TEST_CLASS(FileReaderUnitTest) {
		TEST_METHOD_INITIALIZE(ObjectSetup) {
			string fileReaderTestFile = "fileReaderTest";
			//std::ifstream src(FILE_DB_TEMPLATE, std::ios::binary);
			//std::ofstream dst(fileReaderTestFile, std::ios::binary | std::ios::trunc);
			//dst << src.rdbuf();
			filereader.FileReader::FileReader(fileReaderTestFile);
		}
		TEST_METHOD_CLEANUP(ObjectReset) {
		}
		TEST_METHOD(FileReader_LoadFromFile) {
			size_t expectedEntries = 31;
			std::vector<Task> v = filereader.readTasksFromFile();
			Assert::AreEqual(true, filereader.isOpen());
			Assert::AreEqual(expectedEntries, v.size());
		}
	};
	TEST_CLASS(GCalMgrUnitTest) {
		TEST_METHOD_INITIALIZE(ObjectSetup) {
			//gcalmgr.GCalMgr::GCalMgr();
		}
		TEST_METHOD(GCalMgr_BasicTest) {

		}
	};
	TEST_CLASS(GCalAuthHandlerUnitTest) {
		TEST_METHOD_INITIALIZE(ObjectSetup) {
			//gcalauth.GCalAuthHandler::GCalAuthHandler();
		}
		TEST_METHOD(GCalAuthHandler_BasicTest) {

		}
		//TEST_METHOD(GCalAuthHandler_RegexEmailMatch) {
		//	std::string EMAIL_VALID_1 = "im@junlem.com";
		//	Assert::AreEqual(true, gcalauth.isValidEmail(EMAIL_VALID_1));
		//	std::string EMAIL_VALID_2 = "junlem@nus.edu.sg";
		//	Assert::AreEqual(true, gcalauth.isValidEmail(EMAIL_VALID_2));
		//	std::string EMAIL_VALID_3 = "my.head.is_spinning@thisisemail.random.tld";
		//	Assert::AreEqual(true, gcalauth.isValidEmail(EMAIL_VALID_3));
		//	std::string EMAIL_NONSENSE_1 = "weirnquiwbeqwioenqiwugqwe"; // random string
		//	Assert::AreEqual(false, gcalauth.isValidEmail(EMAIL_NONSENSE_1));
		//	std::string EMAIL_NONSENSE_2 = "@wherediditgo.com"; // no username
		//	Assert::AreEqual(false, gcalauth.isValidEmail(EMAIL_NONSENSE_2));
		//	std::string EMAIL_NONSENSE_3 = "lol@hi"; // no tld
		//	Assert::AreEqual(false, gcalauth.isValidEmail(EMAIL_NONSENSE_3));
		//	std::string EMAIL_NONSENSE_4 = "...@hi.com"; // alphanumeric start and end of username
		//	Assert::AreEqual(false, gcalauth.isValidEmail(EMAIL_NONSENSE_4));
		//	std::string EMAIL_NONSENSE_5 = "!@#$%@hi.com"; // impossible symbols
		//	Assert::AreEqual(false, gcalauth.isValidEmail(EMAIL_NONSENSE_5));
		//	std::string EMAIL_NONSENSE_6 = "a.b@hi.14"; // number in TLD
		//	Assert::AreEqual(false, gcalauth.isValidEmail(EMAIL_NONSENSE_6));
		//}
	};
	std::string responseOneEvent = "{\"kind\":\"calendar#events\",\"etag\":\"\\\"2DaeHpkENZGECFHdcr5l8tYxjD4/jfVA7x8B0H-aSO0c1CWlYdIQZAM\\\"\", \"summary\":\"Wang Jun Lem\", \"updated\" : \"2014-03-30T13:02:13.975Z\", \"timeZone\" : \"Asia/Kuala_Lumpur\", \"accessRole\" : \"owner\", \"defaultReminders\" : [{\"method\":\"popup\", \"minutes\" : 10}, { \"method\":\"popup\", \"minutes\" : 60 }], \"nextPageToken\" : \"CigKGjhtaHNpdWZibjYzZ3RlcnVib2oyZjlkbm9rGAEggICA7MzftZ8TGg0IABIAGNj_wNmour0C\", \"items\" : [{\"kind\":\"calendar#event\", \"etag\" : \"\\\"2DaeHpkENZGECFHdcr5l8tYxjD4/MTMyMjUzODQ4NzAwMDAwMA\\\"\", \"id\" : \"8mhsiufbn63gteruboj2f9dnok\", \"status\" : \"confirmed\", \"htmlLink\" : \"https://www.google.com/calendar/event?eid=OG1oc2l1ZmJuNjNndGVydWJvajJmOWRub2sgaW1AanVubGVtLmNvbQ\", \"created\" : \"2011-11-29T03:47:43.000Z\", \"updated\" : \"2011-11-29T03:48:07.000Z\", \"summary\" : \"Meeting with Mr. Jerome Lo\", \"location\" : \"ETD Office\", \"creator\" : {\"email\":\"im@junlem.com\", \"displayName\" : \"Jun Lem Wang\", \"self\" : true}, \"organizer\" : {\"email\":\"im@junlem.com\", \"displayName\" : \"Jun Lem Wang\", \"self\" : true}, \"start\" : {\"dateTime\":\"2011-11-30T10:00:00+08:00\"}, \"end\" : {\"dateTime\":\"2011-11-30T11:00:00+08:00\"}, \"iCalUID\" : \"8mhsiufbn63gteruboj2f9dnok@google.com\", \"sequence\" : 0, \"reminders\" : {\"useDefault\":false, \"overrides\" : [{\"method\":\"sms\", \"minutes\" : 45}]}}]}";
	size_t responseOneEvent_expectedSize = 1;
	std::string responseFiveEvents = "{ \"kind\": \"calendar#events\", \"etag\": \"\\\"brXLH9dIsANhw0fUafNoxUtvJn8/JMd7kQwDhK0uKObvz5glKvv9zps\\\"\", \"summary\": \"Twentyfifth\", \"updated\": \"2014-04-14T09:22:04.019Z\", \"timeZone\": \"Asia/Singapore\", \"accessRole\": \"owner\", \"items\": [  {   \"kind\": \"calendar#event\",   \"etag\": \"\\\"brXLH9dIsANhw0fUafNoxUtvJn8/MTM5NzQ1NzUzNTY1NTAwMA\\\"\",   \"id\": \"7v5sgigl8ca2h4nlg5468dv3ig\",   \"status\": \"confirmed\",   \"htmlLink\": \"https://www.google.com/calendar/event?eid=N3Y1c2dpZ2w4Y2EyaDRubGc1NDY4ZHYzaWcgdGJsNHFqZDg2ZWcyMGYyMzdlMnVxcThlcnNAZw\",   \"created\": \"2014-04-14T06:38:55.000Z\",   \"updated\": \"2014-04-14T06:38:55.655Z\",   \"summary\": \"Seminar on good coding practices\",   \"creator\": {    \"email\": \"twentyfifthtest@gmail.com\",    \"displayName\": \"Twentyfifth Test Account\"   },   \"organizer\": {    \"email\": \"tbl4qjd86eg20f237e2uqq8ers@group.calendar.google.com\",    \"displayName\": \"Twentyfifth\",    \"self\": true   },   \"start\": {    \"dateTime\": \"2014-04-17T15:00:00+08:00\",    \"timeZone\": \"Asia/Singapore\"   },   \"end\": {    \"dateTime\": \"2014-04-17T17:00:00+08:00\",    \"timeZone\": \"Asia/Singapore\"   },   \"iCalUID\": \"7v5sgigl8ca2h4nlg5468dv3ig@google.com\",   \"sequence\": 0,   \"reminders\": {    \"useDefault\": true   }  },  {   \"kind\": \"calendar#event\",   \"etag\": \"\\\"brXLH9dIsANhw0fUafNoxUtvJn8/MTM5NzQ1NzUzNzY2MDAwMA\\\"\",   \"id\": \"mtkm4eba8alnj8dv0456a7t59o\",   \"status\": \"confirmed\",   \"htmlLink\": \"https://www.google.com/calendar/event?eid=bXRrbTRlYmE4YWxuajhkdjA0NTZhN3Q1OW8gdGJsNHFqZDg2ZWcyMGYyMzdlMnVxcThlcnNAZw\",   \"created\": \"2014-04-14T06:38:57.000Z\",   \"updated\": \"2014-04-14T06:38:57.660Z\",   \"summary\": \"German exams\",   \"location\": \"NUS\",   \"creator\": {    \"email\": \"twentyfifthtest@gmail.com\",    \"displayName\": \"Twentyfifth Test Account\"   },   \"organizer\": {    \"email\": \"tbl4qjd86eg20f237e2uqq8ers@group.calendar.google.com\",    \"displayName\": \"Twentyfifth\",    \"self\": true   },   \"start\": {    \"dateTime\": \"2014-04-23T18:00:00+08:00\",    \"timeZone\": \"Asia/Singapore\"   },   \"end\": {    \"dateTime\": \"2014-04-23T20:00:00+08:00\",    \"timeZone\": \"Asia/Singapore\"   },   \"iCalUID\": \"mtkm4eba8alnj8dv0456a7t59o@google.com\",   \"sequence\": 0,   \"reminders\": {    \"useDefault\": true   }  },  {   \"kind\": \"calendar#event\",   \"etag\": \"\\\"brXLH9dIsANhw0fUafNoxUtvJn8/MTM5NzQ1ODAzODk3NTAwMA\\\"\",   \"id\": \"qe0c05bg59a8m418cmu074p1gs\",   \"status\": \"confirmed\",   \"htmlLink\": \"https://www.google.com/calendar/event?eid=cWUwYzA1Ymc1OWE4bTQxOGNtdTA3NHAxZ3MgdGJsNHFqZDg2ZWcyMGYyMzdlMnVxcThlcnNAZw\",   \"created\": \"2014-04-14T06:47:18.000Z\",   \"updated\": \"2014-04-14T06:47:18.975Z\",   \"summary\": \"Dinner\",   \"location\": \"NUS\",   \"creator\": {    \"email\": \"twentyfifthtest@gmail.com\",    \"displayName\": \"Twentyfifth Test Account\"   },   \"organizer\": {    \"email\": \"tbl4qjd86eg20f237e2uqq8ers@group.calendar.google.com\",    \"displayName\": \"Twentyfifth\",    \"self\": true   },   \"start\": {    \"dateTime\": \"2014-04-14T19:00:00+08:00\",    \"timeZone\": \"Asia/Singapore\"   },   \"end\": {    \"dateTime\": \"2014-04-14T20:00:00+08:00\",    \"timeZone\": \"Asia/Singapore\"   },   \"iCalUID\": \"qe0c05bg59a8m418cmu074p1gs@google.com\",   \"sequence\": 0,   \"reminders\": {    \"useDefault\": true   }  },  {   \"kind\": \"calendar#event\",   \"etag\": \"\\\"brXLH9dIsANhw0fUafNoxUtvJn8/MTM5NzQ1ODE2NzM5MTAwMA\\\"\",   \"id\": \"f8skni0j9ufv4hhrj6oiu2sutc\",   \"status\": \"confirmed\",   \"htmlLink\": \"https://www.google.com/calendar/event?eid=Zjhza25pMGo5dWZ2NGhocmo2b2l1MnN1dGMgdGJsNHFqZDg2ZWcyMGYyMzdlMnVxcThlcnNAZw\",   \"created\": \"2014-04-14T06:49:27.000Z\",   \"updated\": \"2014-04-14T06:49:27.391Z\",   \"summary\": \"Prom night\",   \"location\": \"Raffles Hotel\",   \"creator\": {    \"email\": \"twentyfifthtest@gmail.com\",    \"displayName\": \"Twentyfifth Test Account\"   },   \"organizer\": {    \"email\": \"tbl4qjd86eg20f237e2uqq8ers@group.calendar.google.com\",    \"displayName\": \"Twentyfifth\",    \"self\": true   },   \"start\": {    \"dateTime\": \"2014-04-19T19:00:00+08:00\",    \"timeZone\": \"Asia/Singapore\"   },   \"end\": {    \"dateTime\": \"2014-04-19T23:00:00+08:00\",    \"timeZone\": \"Asia/Singapore\"   },   \"iCalUID\": \"f8skni0j9ufv4hhrj6oiu2sutc@google.com\",   \"sequence\": 0,   \"reminders\": {    \"useDefault\": true   }  },  {   \"kind\": \"calendar#event\",   \"etag\": \"\\\"brXLH9dIsANhw0fUafNoxUtvJn8/MTM5NzQ1ODcwMzIyMzAwMA\\\"\",   \"id\": \"56nbr2ar9bvfkp4afrt9c06ah4\",   \"status\": \"confirmed\",   \"htmlLink\": \"https://www.google.com/calendar/event?eid=NTZuYnIyYXI5YnZma3A0YWZydDljMDZhaDQgdGJsNHFqZDg2ZWcyMGYyMzdlMnVxcThlcnNAZw\",   \"created\": \"2014-04-14T06:58:23.000Z\",   \"updated\": \"2014-04-14T06:58:23.223Z\",   \"summary\": \"Friend's birthday party\",   \"creator\": {    \"email\": \"twentyfifthtest@gmail.com\",    \"displayName\": \"Twentyfifth Test Account\"   },   \"organizer\": {    \"email\": \"tbl4qjd86eg20f237e2uqq8ers@group.calendar.google.com\",    \"displayName\": \"Twentyfifth\",    \"self\": true   },   \"start\": {    \"dateTime\": \"2014-04-22T17:00:00+08:00\",    \"timeZone\": \"Asia/Singapore\"   },   \"end\": {    \"dateTime\": \"2014-04-22T23:00:00+08:00\",    \"timeZone\": \"Asia/Singapore\"   },   \"iCalUID\": \"56nbr2ar9bvfkp4afrt9c06ah4@google.com\",   \"sequence\": 0,   \"reminders\": {    \"useDefault\": true   }  } ]}";
	size_t responseFiveEvents_expectedSize = 5;
	std::string responseCalendarList = "{ \"kind\": \"calendar#calendarList\", \"etag\": \"\\\"brXLH9dIsANhw0fUafNoxUtvJn8/MWP8FJWYMb3Q2heJB_IrojxSB20\\\"\", \"items\": [  {   \"kind\": \"calendar#calendarListEntry\",   \"etag\": \"\\\"brXLH9dIsANhw0fUafNoxUtvJn8/ZxOZlKsa4paH6gsyGZP30rdCeyw\\\"\",   \"id\": \"tbl4qjd86eg20f237e2uqq8ers@group.calendar.google.com\",   \"summary\": \"Twentyfifth\",   \"timeZone\": \"Asia/Singapore\",   \"colorId\": \"21\",   \"backgroundColor\": \"#cca6ac\",   \"foregroundColor\": \"#000000\",   \"selected\": true,   \"accessRole\": \"owner\"  },  {   \"kind\": \"calendar#calendarListEntry\",   \"etag\": \"\\\"brXLH9dIsANhw0fUafNoxUtvJn8/UCkIMY3PoTcvdtNNdWkmKaI-d8Q\\\"\",   \"id\": \"twentyfifthtest@gmail.com\",   \"summary\": \"twentyfifthtest@gmail.com\",   \"timeZone\": \"Asia/Singapore\",   \"colorId\": \"17\",   \"backgroundColor\": \"#9a9cff\",   \"foregroundColor\": \"#000000\",   \"selected\": true,   \"accessRole\": \"owner\",   \"defaultReminders\": [    {     \"method\": \"popup\",     \"minutes\": 30    }   ],   \"notificationSettings\": {    \"notifications\": [     {      \"type\": \"eventCreation\",      \"method\": \"email\"     },     {      \"type\": \"eventChange\",      \"method\": \"email\"     },     {      \"type\": \"eventCancellation\",      \"method\": \"email\"     },     {      \"type\": \"eventResponse\",      \"method\": \"email\"     }    ]   },   \"primary\": true  },  {   \"kind\": \"calendar#calendarListEntry\",   \"etag\": \"\\\"brXLH9dIsANhw0fUafNoxUtvJn8/f-bK2gI6xwP95G85eiKKelWciZY\\\"\",   \"id\": \"#contacts@group.v.calendar.google.com\",   \"summary\": \"Contacts' birthdays and events\",   \"description\": \"Your contacts' birthdays and anniversaries\",   \"timeZone\": \"Asia/Singapore\",   \"colorId\": \"2\",   \"backgroundColor\": \"#d06b64\",   \"foregroundColor\": \"#000000\",   \"selected\": true,   \"accessRole\": \"reader\"  },  {   \"kind\": \"calendar#calendarListEntry\",   \"etag\": \"\\\"brXLH9dIsANhw0fUafNoxUtvJn8/gic-kKNZQ_wzEr4a-6AjaGxGAEs\\\"\",   \"id\": \"en.singapore#holiday@group.v.calendar.google.com\",   \"summary\": \"Holidays in Singapore\",   \"description\": \"Holidays in Singapore\",   \"timeZone\": \"Asia/Singapore\",   \"colorId\": \"17\",   \"backgroundColor\": \"#9a9cff\",   \"foregroundColor\": \"#000000\",   \"selected\": true,   \"accessRole\": \"reader\"  } ]}";
	size_t responseCalendarList_expectedSize = 4;
	int responseCalendarList_expectedPosOfEmail = 1;
	string responseCalendarList_expectedString = "twentyfifthtest@gmail.com";
	TEST_CLASS(GCalParserUnitTest) {
		TEST_METHOD_INITIALIZE(GCalParserTest_Initialize) {
		}
		TEST_METHOD(GCalParserTest) {
			std::vector<Task> tasks = parser.parseResponseToTasks(responseOneEvent);
			Assert::AreEqual(responseOneEvent_expectedSize, tasks.size());
		}
		TEST_METHOD(GCalParser_ParseCalendarList) {
			vector<map<string, string>> v = parser.parseResponseToCalendars(responseCalendarList);
			Assert::AreEqual(responseCalendarList_expectedSize, v.size());
		}
		TEST_METHOD(GCalParser_ParseEventsList) {
			vector<Task> vt = parser.parseResponseToTasks(responseFiveEvents);
			Assert::AreEqual(responseFiveEvents_expectedSize, vt.size());
		}
		TEST_METHOD(GCalParser_MultiLevel) {
			map<string, string> responseMap = parser.parseJsonToMap(responseCalendarList);
			vector<map<string, string>> responses = parser.parseJsonArrayToVector(responseMap.at("items"));
			Assert::AreEqual(responseCalendarList_expectedString, responses[responseCalendarList_expectedPosOfEmail].at("id"));
		}
	};
	TEST_CLASS(GCalRequestHandlerUnitTest) {
		TEST_METHOD(GCalRequestHandler_Basic) {
		}
	};
	GCalVariableMgr varmgr;
	TEST_CLASS(GCalVariableMgrTest) {
		TEST_CLASS_INITIALIZE(GCalVariableMgr_Initialize) {
			varmgr.GCalVariableMgr::GCalVariableMgr();
		}
		TEST_METHOD(GCalVarMgr_CheckDefaultValuesExist) {
			Assert::IsTrue(varmgr.exists(GCalVariableMgr::LABEL_CLIENT_ID));
			Assert::IsTrue(varmgr.exists(GCalVariableMgr::LABEL_CLIENT_SECRET));
		}
		TEST_METHOD(GCalVarMgr_setAndGetValues) {
			string LABEL_TEST = "test";
			string VALUE_TEST = "this is a long string for testing purposes.";
			varmgr.setValue(LABEL_TEST, VALUE_TEST);
			Assert::AreEqual(VALUE_TEST, varmgr.getValue(LABEL_TEST));
		}
		TEST_METHOD(GCalVarMgr_ReadAndWriteFromFile) {
			GCalVariableMgr varmgr2;
			string LABEL_TEST = "test";
			string VALUE_TEST = "this is a long string for testing purposes.";
			Assert::AreEqual(VALUE_TEST, varmgr.getValue(LABEL_TEST));
		}
		TEST_METHOD(GCalVarMgr_ConfirmClear) {
			string NONSENSE = "nonsense lala";
			string LABEL_TEST = "test";
			Assert::IsTrue(varmgr.exists(LABEL_TEST));
			fstream file(FILE_GOOGLE, ios::out | ios::trunc);
			Assert::IsTrue(file.is_open());
			file << NONSENSE;
			file.close();
			GCalVariableMgr varmgr2;
			Assert::IsFalse(varmgr2.exists(LABEL_TEST));
		}
	};

}